package org.enhance.web.util;

import org.enhance.common.constant.ResCodeConst;
import org.enhance.common.exception.EnhanceRuntimeException;
import org.enhance.common.util.ExceptionUtil;
import org.enhance.web.exception.HttpStatusRuntimeException;
import org.enhance.web.vo.ResponseResult;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;

public class ResUtil {
    private ResUtil() {
        throw new IllegalStateException("Constant class");
    }

    public static ResponseResult<Void> ok() {
        return ok(null, null);
    }

    public static <T> ResponseResult<T> ok(T data) {
        return ok(null, data);
    }

    public static <T> ResponseResult<T> ok(String msg, T data) {
        return generateResponseResult(ResCodeConst.OK, msg, data);
    }

    public static <T> ResponseResult<T> failure(String msg) {
        return generateResponseResult(ResCodeConst.BAD_REQUEST, msg, null);
    }

    public static <T> ResponseEntity<ResponseResult<T>> failure(Throwable throwable) {
        String msg = throwable.getMessage();
        if (throwable instanceof EnhanceRuntimeException) {
            EnhanceRuntimeException enhanceRuntimeException = (EnhanceRuntimeException) throwable;
            return generateResponseResult(enhanceRuntimeException.getStatus(), null, msg, null, enhanceRuntimeException.getErrorCode(), enhanceRuntimeException.getErrorArgs());
        } else {
            HttpStatus status = HttpStatus.INTERNAL_SERVER_ERROR;
            if (throwable instanceof HttpStatusRuntimeException) {
                status = ((HttpStatusRuntimeException) throwable).getStatus();
            }
            T data = (T) ExceptionUtil.toMessage(throwable);
            return generateResponseResult(String.valueOf(status.value()), status, msg, data, null, null);
        }
    }

    private static <T> ResponseResult<T> generateResponseResult(String code, String msg, T data) {
        ResponseResult<T> responseResult = new ResponseResult<>();
        responseResult.setCode(code);
        responseResult.setData(data);
        responseResult.setMsg(msg);
        return responseResult;
    }

    private static <T> ResponseEntity<ResponseResult<T>> generateResponseResult(String code, HttpStatus httpStatus, String msg, T data, String errorCode, String[] errorArgs) {
        ResponseResult<T> responseResult = new ResponseResult<>();
        responseResult.setCode(code);
        responseResult.setData(data);
        responseResult.setMsg(msg);
        responseResult.addError(errorCode, errorArgs);
        if (httpStatus != null) {
            return ResponseEntity.status(httpStatus).body(responseResult);
        } else {
            return ResponseEntity.ok(responseResult);
        }
    }
}